CMAKE_MINIMUM_REQUIRED(VERSION 3.10)

SET ( RBDL_VERSION_MAJOR 3 )
SET ( RBDL_VERSION_MINOR 3 )
SET ( RBDL_VERSION_PATCH 1 )
SET ( RBDL_VERSION 
	${RBDL_VERSION_MAJOR}.${RBDL_VERSION_MINOR}.${RBDL_VERSION_PATCH}
)
SET ( RBDL_SO_VERSION 
	${RBDL_VERSION_MAJOR}.${RBDL_VERSION_MINOR}.${RBDL_VERSION_PATCH}
)
SET (PROJECT_VERSION ${RBDL_VERSION})
PROJECT (RBDL VERSION ${RBDL_VERSION})

LIST( APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/CMake )


# SET (CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")

INCLUDE(GNUInstallDirs)

SET_TARGET_PROPERTIES ( ${PROJECT_EXECUTABLES} PROPERTIES
		LINKER_LANGUAGE CXX
	)

# Set a default build type to 'Release' if none was specified
IF(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
	MESSAGE(STATUS "Setting build type to 'Release' as none was specified.")
	SET(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build." FORCE)
  # Set the possible values of build type for cmake-gui
  SET_PROPERTY(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo")
ENDIF()

IF (MSVC)
  SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /bigobj /permissive- /std:c++17")
ENDIF (MSVC)

IF(APPLE)
  SET(CMAKE_CXX_STANDARD 17)
  INCLUDE_DIRECTORIES("/usr/local/include")
ENDIF(APPLE)

IF ( ${CMAKE_VERSION} VERSION_LESS 3.12.0 )
	ADD_DEFINITIONS (-D_SILENCE_ALL_CXX17_DEPRECATION_WARNINGS)
ELSE( ${CMAKE_VERSION} VERSION_LESS 3.12.0 )
	ADD_COMPILE_DEFINITIONS (_SILENCE_ALL_CXX17_DEPRECATION_WARNINGS)
ENDIF( ${CMAKE_VERSION} VERSION_LESS 3.12.0 )


SET (RBDL_BUILD_COMPILER_ID ${CMAKE_CXX_COMPILER_ID})
SET (RBDL_BUILD_COMPILER_VERSION ${CMAKE_CXX_COMPILER_VERSION})

# Options
SET (RBDL_BUILD_STATIC_DEFAULT OFF)
OPTION (RBDL_BUILD_STATIC "Build statically linked library (otherwise dynamiclly linked)" ${RBDL_BUILD_STATIC_DEFAULT})
OPTION (RBDL_BUILD_TESTS "Build the test executables" OFF)
OPTION (RBDL_ENABLE_LOGGING "Enable logging (warning: major impact on performance!)" OFF)
OPTION (RBDL_STORE_VERSION "Enable storing of version information in the library (requires build from valid repository)" OFF)
OPTION (RBDL_BUILD_ADDON_URDFREADER "Build the (experimental) urdf reader" OFF)
OPTION (RBDL_BUILD_ADDON_BENCHMARK "Build the benchmarking tool" OFF)
OPTION (RBDL_BUILD_ADDON_LUAMODEL "Build the lua model reader" OFF)
OPTION (RBDL_BUILD_PYTHON_WRAPPER "Build experimental python wrapper" OFF)
OPTION (RBDL_BUILD_ADDON_GEOMETRY "Build the geometry library" OFF)
OPTION (RBDL_BUILD_ADDON_MUSCLE "Build the muscle library" OFF)
OPTION (RBDL_BUILD_ADDON_MUSCLE_FITTING "Build muscle library fitting functions (requires Ipopt)" OFF)
OPTION (RBDL_BUILD_ADDON_BALANCE "Build balance library" OFF)
OPTION (RBDL_BUILD_EXECUTABLES "Build addon executables, disable this if you only want to build the libraries." ON)
OPTION (RBDL_USE_PYTHON_2 "Use python 2 instead of python 3" OFF)
OPTION (RBDL_BUILD_CASADI "Use the CasADi backend" OFF)
OPTION (RBDL_VCPKG_BUILD "Building RBDL in vcpkg environment" OFF)


# Find and use the system's Eigen3 library
FIND_PACKAGE (Eigen3 3.0.0)

IF (NOT EIGEN3_FOUND)
    MESSAGE (WARNING "Could not find Eigen3 on your system. Please install it!")
ENDIF (NOT EIGEN3_FOUND)

INCLUDE_DIRECTORIES (${EIGEN3_INCLUDE_DIR})

# Addons
IF (RBDL_BUILD_ADDON_URDFREADER)
  ADD_SUBDIRECTORY ( addons/urdfreader )
  IF(RBDL_BUILD_TESTS)
    ADD_SUBDIRECTORY ( addons/urdfreader/tests )
  ENDIF(RBDL_BUILD_TESTS)
ENDIF (RBDL_BUILD_ADDON_URDFREADER)

IF (RBDL_BUILD_ADDON_BENCHMARK)
  ADD_SUBDIRECTORY ( addons/benchmark )
ENDIF (RBDL_BUILD_ADDON_BENCHMARK)

IF (RBDL_BUILD_CASADI)
  ADD_SUBDIRECTORY( casadi )
ENDIF (RBDL_BUILD_CASADI)

IF(RBDL_BUILD_ADDON_MUSCLE)
  SET(RBDL_BUILD_ADDON_GEOMETRY ON CACHE BOOL "Build the geometry library" FORCE)
  IF (RBDL_BUILD_ADDON_MUSCLE_FITTING)
    SET(CUSTOM_IPOPT_PATH "" CACHE PATH "Path to specific IPOPT Installation")
  ENDIF (RBDL_BUILD_ADDON_MUSCLE_FITTING)
  ADD_SUBDIRECTORY ( addons/muscle )
  IF(RBDL_BUILD_TESTS)
  	ADD_SUBDIRECTORY ( addons/muscle/tests ) 
  ENDIF(RBDL_BUILD_TESTS)
ENDIF(RBDL_BUILD_ADDON_MUSCLE)


IF(RBDL_BUILD_ADDON_GEOMETRY)
  ADD_SUBDIRECTORY ( addons/geometry )
  IF(RBDL_BUILD_TESTS)
  	ADD_SUBDIRECTORY ( addons/geometry/tests ) 
  ENDIF(RBDL_BUILD_TESTS)
ENDIF(RBDL_BUILD_ADDON_GEOMETRY)

IF(RBDL_BUILD_ADDON_BALANCE)
  ADD_SUBDIRECTORY ( addons/balance )
  IF(RBDL_BUILD_TESTS)
    ADD_SUBDIRECTORY ( addons/balance/tests ) 
  ENDIF(RBDL_BUILD_TESTS)
ENDIF(RBDL_BUILD_ADDON_BALANCE)

IF (RBDL_BUILD_ADDON_LUAMODEL)
  ADD_SUBDIRECTORY ( addons/luamodel )
  IF(RBDL_BUILD_TESTS)
    ADD_SUBDIRECTORY ( addons/luamodel/tests )
  ENDIF(RBDL_BUILD_TESTS)
ENDIF (RBDL_BUILD_ADDON_LUAMODEL)

IF (RBDL_BUILD_TESTS)
 ADD_SUBDIRECTORY ( tests )
ENDIF (RBDL_BUILD_TESTS)

# Source files for RBDL
SET ( RBDL_SOURCES 
	src/rbdl_version.cc
	src/rbdl_mathutils.cc
	src/rbdl_utils.cc
	src/rbdl_errors.cc
	src/Constraints.cc
  src/Constraint_Contact.cc
  src/Constraint_Loop.cc  
	src/Dynamics.cc
	src/Logging.cc
	src/Joint.cc
	src/Model.cc
	src/Kinematics.cc
	)

# Static / dynamic builds
IF (RBDL_BUILD_STATIC)
  ADD_LIBRARY ( rbdl-static STATIC ${RBDL_SOURCES} )
  TARGET_INCLUDE_DIRECTORIES(rbdl-static PUBLIC
    ${CMAKE_CURRENT_SOURCE_DIR}/include
    ${CMAKE_CURRENT_BINARY_DIR}/include
    ${CMAKE_SOURCE_DIR}/tests
  )
  IF (NOT WIN32)
    SET_TARGET_PROPERTIES ( rbdl-static PROPERTIES PREFIX "lib")
  ENDIF (NOT WIN32)
  SET_TARGET_PROPERTIES ( rbdl-static PROPERTIES OUTPUT_NAME "rbdl")

	IF (RBDL_BUILD_ADDON_LUAMODEL)
		TARGET_LINK_LIBRARIES ( rbdl-static
			rbdl_luamodel-static
			)
	ENDIF (RBDL_BUILD_ADDON_LUAMODEL)
  IF (RBDL_BUILD_ADDON_URDFREADER)
		TARGET_LINK_LIBRARIES ( rbdl-static
			rbdl_urdfreader-static
			)
  ENDIF (RBDL_BUILD_ADDON_URDFREADER)
  IF (RBDL_BUILD_CASADI)
      TARGET_LINK_LIBRARIES ( rbdl-static
                          ${Casadi_LIBRARY}
                          )
  ENDIF (RBDL_BUILD_CASADI)

	INSTALL (TARGETS rbdl-static
	  LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
		ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
	)
ELSE (RBDL_BUILD_STATIC)
	ADD_LIBRARY ( rbdl SHARED ${RBDL_SOURCES} )
  TARGET_INCLUDE_DIRECTORIES(rbdl PUBLIC
    ${CMAKE_CURRENT_SOURCE_DIR}/include
    ${CMAKE_CURRENT_BINARY_DIR}/include
    ${CMAKE_SOURCE_DIR}/tests
  )
	SET_TARGET_PROPERTIES ( rbdl PROPERTIES
		VERSION ${RBDL_VERSION}
		SOVERSION ${RBDL_SO_VERSION}
		)

        IF (RBDL_BUILD_CASADI)
            TARGET_LINK_LIBRARIES ( rbdl
                ${Casadi_LIBRARY}
                )
        ENDIF (RBDL_BUILD_CASADI)

	INSTALL (TARGETS rbdl
		LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
		ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
		)
ENDIF (RBDL_BUILD_STATIC)

IF (RBDL_STORE_VERSION)
	# Set versioning information that can be queried during runtime
	EXECUTE_PROCESS(COMMAND "git" "rev-parse" "HEAD"
			WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
			OUTPUT_VARIABLE RBDL_BUILD_COMMIT)
	STRING(REGEX REPLACE "\n$" "" RBDL_BUILD_COMMIT "${RBDL_BUILD_COMMIT}")
	EXECUTE_PROCESS(COMMAND "git" "describe" "--all" "--dirty" "--long"
			WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
			OUTPUT_VARIABLE RBDL_BUILD_BRANCH)
	STRING(REGEX REPLACE "\n$" "" RBDL_BUILD_BRANCH "${RBDL_BUILD_BRANCH}")
	SET (RBDL_BUILD_TYPE ${CMAKE_BUILD_TYPE})
ELSE (RBDL_STORE_VERSION)
	SET (RBDL_BUILD_COMMIT "unknown")
	SET (RBDL_BUILD_BRANCH "unknown")
	SET (RBDL_BUILD_TYPE "unknown")
ENDIF (RBDL_STORE_VERSION)

CONFIGURE_FILE (
	"${CMAKE_CURRENT_SOURCE_DIR}/include/rbdl/rbdl_config.h.cmake" 
	"${CMAKE_CURRENT_BINARY_DIR}/include/rbdl/rbdl_config.h"
	)

# Python wrapper
IF (RBDL_BUILD_PYTHON_WRAPPER)
	add_subdirectory ( python )
ENDIF (RBDL_BUILD_PYTHON_WRAPPER)

# Installation
FILE ( GLOB headers 
	${CMAKE_CURRENT_SOURCE_DIR}/include/rbdl/*.h
	${CMAKE_CURRENT_BINARY_DIR}/include/rbdl/rbdl_config.h
	)

INSTALL ( FILES ${headers} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/rbdl )

# pkg-config
CONFIGURE_FILE (
  ${CMAKE_CURRENT_SOURCE_DIR}/share/rbdl.pc.cmake
  ${CMAKE_CURRENT_BINARY_DIR}/rbdl.pc @ONLY
  )
INSTALL (
  FILES  ${CMAKE_CURRENT_BINARY_DIR}/rbdl.pc
  DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig
  )

# Prepare share
if(WIN32 AND NOT CYGWIN AND NOT RBDL_VCPKG_BUILD)
  set(CMAKE_SHARE_DIR cmake)
else()
  set(CMAKE_SHARE_DIR lib/cmake/RBDL)
endif()
include(CMakePackageConfigHelpers)
configure_package_config_file(
  share/RBDLConfig.cmake.in
  ${CMAKE_CURRENT_BINARY_DIR}/RBDLConfig.cmake
  INSTALL_DESTINATION ${CMAKE_SHARE_DIR}
)
INSTALL (
  FILES  ${CMAKE_CURRENT_BINARY_DIR}/RBDLConfig.cmake
  DESTINATION ${CMAKE_SHARE_DIR}
  )

# Packaging
SET(CPACK_GENERATOR "DEB")
SET(CPACK_DEBIAN_PACKAGE_MAINTAINER "Martin Felis <martin@fysx.org>")
SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "the Rigid Body Dynamics Library (RBDL)")
SET(CPACK_PACKAGE_VENDOR "Martin Felis")
SET(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/README.md")
SET(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE")
SET(CPACK_PACKAGE_VERSION_MAJOR ${RBDL_VERSION_MAJOR})
SET(CPACK_PACKAGE_VERSION_MINOR ${RBDL_VERSION_MINOR})
SET(CPACK_PACKAGE_VERSION_PATCH ${RBDL_VERSION_PATCH})
SET(CPACK_PACKAGE_INSTALL_DIRECTORY "CPACK_PACKAGE ${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}")
SET(CPACK_PACKAGE_FILE_NAME "rbdl-${CMAKE_LIBRARY_ARCHITECTURE}-${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}")
SET(CPACK_PACKAGE_EXECUTABLES "rbdl_luamodel_util;RBDL Lua Model Utility")

INCLUDE(CPack)
